using System;
using System.Management;
using System.Globalization;

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace CodePlex.Diagnostics
{
    /// <summary>
    /// Represents a physical network adapter.
    /// </summary>
    public class NetworkAdapter : Device
    {
        #region NetworkAdapter Private Fields

        private string m_macAddress;

        #endregion

        #region public NetworkAdapter()

        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkAdapter"/> class.
        /// </summary>
        public NetworkAdapter()
        {
        }

        #endregion

        #region public static IList<NetworkAdapter> GetNetworkAdapters()

        /// <summary>
        /// Gets an <see cref="T:System.Collections.Generic.IList`1"/> containin a <see cref="T:NetworkAdapter"/> instance for each physical network adapter.
        /// </summary>
        /// <remarks>
        /// The <see cref="M:NetworkAdapter.GetNetworkAdapters"/> method is implemented as a method and not a property because the list of network adapters will take considerably longer
        /// to retrieve than a simple field. Static code analysis warning CA1024 is therefore suppressed after consulting the .NET Framework Design Guidelines written by Brad Abrams and 
        /// Krzysztof Cwalina which is published by Addison Wesley.
        /// </remarks>
        /// <returns>An <see cref="T:System.Collections.Generic.IList`1"/> containin a <see cref="T:NetworkAdapter"/> instance for each physical network adatpter.</returns>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        public static IList<NetworkAdapter> GetNetworkAdapters()
        {
            try
            {
                List<NetworkAdapter> adapters = new List<NetworkAdapter>();

                ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT * FROM Win32_NetworkAdapter");

                foreach (ManagementObject managementObject in searcher.Get())
                {
                    NetworkAdapter adapter = new NetworkAdapter();

                    adapter.Name = managementObject["Name"] as string;
                    adapter.Description = managementObject["Description"] as string;
                    adapter.DeviceId = managementObject["DeviceID"] as string;

                    adapter.MacAddress = managementObject["MacAddress"] as string;

                    adapters.Add(adapter);
                }

                return new ReadOnlyCollection<NetworkAdapter>(adapters);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                Trace.WriteLine(ex.StackTrace);

                throw;
            }
        }

        #endregion

        #region public string MacAddress

        /// <summary>
        /// Gets the network adapter's Mac address.
        /// </summary>
        /// <value>The network adapter's Mac address.</value>
        public string MacAddress
        {
            get
            {
                return m_macAddress;
            }
            private set
            {
                m_macAddress = value;
            }
        }

        #endregion
    }
}
